// ============================================================================
// TypeORM 数据源配置
// ============================================================================

import 'reflect-metadata'
import { DataSource } from 'typeorm'
import { join } from 'path'
import { app } from 'electron'
import { logger } from '@roasmax/logger'
import { CustomTypeOrmLogger } from './custom-logger'

// 导入所有实体
import {
  Account,
  Task,
  TaskLog,
  WeiboData,
  User,
  Config,
  KeywordCrawlWindow
} from './entities'

/**
 * 获取数据库路径
 */
function getDatabasePath(): string {
  const userDataPath = app.getPath('userData')
  return join(userDataPath, 'weibo-scraper.db')
}

/**
 * TypeORM 数据源配置
 */
export const AppDataSource = new DataSource({
  type: 'better-sqlite3',
  database: getDatabasePath(),
  entities: [
    Account,
    Task,
    TaskLog,
    WeiboData,
    User,
    Config,
    KeywordCrawlWindow
  ],
  synchronize: true,
  logging: false,
  logger: new CustomTypeOrmLogger(), // 使用自定义日志器，避免ansis依赖
  cache: {
    duration: 30000, // 30秒缓存
    type: 'database'
  },
  extra: {
    // SQLite 特定配置
    pragma: {
      journal_mode: 'WAL',
      synchronous: 'NORMAL',
      cache_size: 1000,
      temp_store: 'memory',
      foreign_keys: 'ON'
    }
  }
})

/**
 * 初始化数据源
 */
export async function initializeDataSource(): Promise<void> {
  try {
    if (!AppDataSource.isInitialized) {
      logger.info('正在初始化 TypeORM 数据源...')
      await AppDataSource.initialize()
      logger.info('TypeORM 数据源初始化成功')
    }
  } catch (error) {
    logger.error('TypeORM 数据源初始化失败:', error)
    throw error
  }
}

/**
 * 关闭数据源
 */
export async function closeDataSource(): Promise<void> {
  try {
    if (AppDataSource.isInitialized) {
      logger.info('正在关闭 TypeORM 数据源...')
      await AppDataSource.destroy()
      logger.info('TypeORM 数据源已关闭')
    }
  } catch (error) {
    logger.error('关闭 TypeORM 数据源失败:', error)
    throw error
  }
}

/**
 * 获取数据源实例
 */
export function getDataSource(): DataSource {
  if (!AppDataSource.isInitialized) {
    throw new Error('数据源尚未初始化，请先调用 initializeDataSource()')
  }
  return AppDataSource
}

/**
 * 获取实体仓库
 */
export function getRepository<T>(entity: new () => T) {
  return getDataSource().getRepository(entity)
}

/**
 * 执行事务
 */
export async function runInTransaction<T>(
  operation: (manager: any) => Promise<T>
): Promise<T> {
  return await AppDataSource.transaction(operation)
}

/**
 * 数据库健康检查
 */
export async function healthCheck(): Promise<boolean> {
  try {
    if (!AppDataSource.isInitialized) {
      return false
    }

    // 执行简单查询测试连接
    await AppDataSource.query('SELECT 1')
    return true
  } catch (error) {
    logger.error('数据库健康检查失败:', error)
    return false
  }
}

/**
 * 获取数据库统计信息
 */
export async function getDatabaseStats() {
  try {
    const stats = {
      accounts: await getRepository(Account).count(),
      tasks: await getRepository(Task).count(),
      taskLogs: await getRepository(TaskLog).count(),
      weiboData: await getRepository(WeiboData).count(),
      users: await getRepository(User).count(),
      configs: await getRepository(Config).count(),
      keywordCrawlWindows: await getRepository(KeywordCrawlWindow).count()
    }

    return stats
  } catch (error) {
    logger.error('获取数据库统计信息失败:', error)
    throw error
  }
}


import { EntityManager } from "typeorm";

export async function createDataSource() {
  return getDataSource()
}

export async function useDataSource<T>(h: (ds: DataSource) => Promise<T>): Promise<T> {
  const ds = await createDataSource()
  return await h(ds)
}

export async function useEntityManager<T>(h: (m: EntityManager) => Promise<T>) {
  return useDataSource(async ds => {
    const m = ds.createEntityManager()
    return await h(m)
  })
}

export async function useTransalation<T>(h: (m: EntityManager) => Promise<T>) {
  return useDataSource(async ds => {
    const m = ds.createEntityManager()
    return await m.transaction(async c => await h(c))
  })
}

export async function useQuery<T>(sql: string, params: any[]): Promise<T> {
  return useEntityManager(async m => m.query(sql, params))
}

export interface QueryFactory<T> {
  (...params: any[]): Promise<T>
}
export function useQueryFactory<T>(sql: string): QueryFactory<T> {
  return (...params: any[]) => {
    return useQuery(sql, params)
  }
}